package cc.shacocloud.luanniao.core.config

import cc.shacocloud.luanniao.core.service.cache.CacheManager
import cc.shacocloud.luanniao.core.service.cache.db.CacheRepository
import cc.shacocloud.luanniao.core.service.cache.db.DBCacheManager
import cc.shacocloud.luanniao.core.service.oss.ObjectStorageService
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.PasswordEncoder
import java.time.format.DateTimeFormatter


/**
 * @author 思追(shaco)
 */
@Configuration
@EnableConfigurationProperties(OssProperties::class, VectorProperties::class, AdminProperties::class)
@ComponentScan(basePackages = ["cc.shacocloud.luanniao.core"])
class CoreConfiguration {

    /**
     * 密码编码器
     */
    @Bean
    fun passwordEncoder(): PasswordEncoder {
        return BCryptPasswordEncoder()
    }

    /**
     * 注册 oss 存储服务 bean
     */
    @Bean(destroyMethod = "destroy")
    fun objectStorageService(properties: OssProperties): ObjectStorageService {
        return ObjectStorageService.getOss(properties)
    }

    /**
     * 默认的缓存管理器
     */
    @Bean
    @ConditionalOnMissingBean(CacheManager::class)
    fun cacheManager(cacheRepository: CacheRepository): CacheManager {
        return DBCacheManager(cacheRepository)
    }

    @Bean
    fun jackson2ObjectMapperBuilderCustomizer(): Jackson2ObjectMapperBuilderCustomizer {
        return Jackson2ObjectMapperBuilderCustomizer { builder ->

            // 格式
            val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            // 反序列化
            builder.deserializers(LocalDateDeserializer(dateFormatter))
            builder.deserializers(LocalDateTimeDeserializer(dateTimeFormatter))

            // 序列化
            builder.serializers(LocalDateSerializer(dateFormatter))
            builder.serializers(LocalDateTimeSerializer(dateTimeFormatter))
        }
    }

}